#include<bits/stdc++.h>

using namespace std;

#define ll long long

const int N=1e5+5;

int T;
int n,m,L,V;
struct node
{
    int d,v,a;
    int l,r;
} car[N];

int p[N];

struct poin
{
    int id1,id2;
    bool operator <(const poin a)
    {
        if(id1==a.id1)
        {
            return id2<a.id2;
        }
        return id1<a.id1;
    }
};

vector<poin> exc;

int main()
{
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);

    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);

    cin>>T;
    while(T--)
    {
        exc.clear();

        cin>>n>>m>>L>>V;
        for(int i=1;i<=n;i++)
        {
            cin>>car[i].d>>car[i].v>>car[i].a;
            car[i].l=car[i].r=0;
            // to record the exceeded segment
            if(car[i].a==0)
            {
                if(car[i].v<=V)
                {
                    car[i].l=1e7;
                    car[i].r=1e7;
                }
                else
                {
                    car[i].l=car[i].d;
                    car[i].r=L;
                }
            }
            else
            {
                double dis=(1.0*(V*V-car[i].v*car[i].v)/(2.0*car[i].a));
                if(dis<0)
                {
                    if(car[i].v>V)
                    {
                        car[i].l=car[i].d;
                        car[i].r=L;
                    }
                    else
                    {
                        car[i].l=1e7;
                        car[i].r=1e7;
                    }
                }
                else
                {
                    if(car[i].a>0)
                    {
                        car[i].l=(int)dis+1+car[i].d;
                        car[i].r=L;
                    }
                    else
                    {
                        car[i].r=ceil(dis)-1+car[i].d;
                        car[i].l=car[i].d;
                    }
                }
            }

        }
        for(int i=1;i<=m;i++)
        {
            cin>>p[i];
        }

        int ans1=0;
        for(int i=1;i<=n;i++)
        {
//            cout<<car[i].l<<" "<<car[i].r<<"\n";
            int id1=lower_bound(p+1,p+1+m,car[i].l)-p;
            int id2=upper_bound(p+1,p+1+m,car[i].r)-1-p;
            if(id1!=m+1&&id2!=0&&id2>=id1)
            {
                exc.push_back({id1,id2});
//                cout<<id1<<" "<<id2<<" id\n";
                ans1++;
            }
        }
        cout<<ans1<<" ";

        sort(exc.begin(),exc.end());
        int curl=0,curr=1e7,ans2=0;
        for(int i=0;i<exc.size();i++)
        {
//            cout<<"id: "<<exc[i].id1<<" "<<exc[i].id2<<"\n";
            if(exc[i].id1<=curr&&exc[i].id2>=curl)
            {
                curl=max(curl,exc[i].id1);
                curr=min(curr,exc[i].id2);
            }
            else
            {
//                cout<<"cur: "<<curl<<" "<<curr<<"\n";
                ans2++;
                curl=exc[i].id1,curr=exc[i].id2;
            }
        }
        if(exc.size())
        {
            ans2++;
        }
        cout<<m-ans2<<"\n";

    }

    return 0;
}
